package com.gem.springbootdemo.service.Impl;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gem.springbootdemo.entity.User;
import com.gem.springbootdemo.mapper.UserMapper;
import com.gem.springbootdemo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.List;

@Service  //实例化一个Service 对象,放置spring工厂
public class UserServiceImpl implements UserService {
    //    调用持久层 ,给接口实例化实现类对象的时候,对象的名字是接口名的第一个字母小写
    @Autowired //按类型注入
//    @Resource  //按名称注入
    private UserMapper userMapper;
    //实例化一个盐对象(传统的方案)
    private BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
    @Autowired   //redisTemplate 属于mapper 与redis数据库交互,封装了增删改查的方法
    private RedisTemplate<String,String>  redisTemplate;

    private ObjectMapper mapper=new ObjectMapper();//负责json与对象之间的转换的操作类

    //查询所有的用户
    @Override
    public List<User> getAllUser() throws IOException {
//        1.从redis缓存中获取数据,数据为字符串 ,json字符串   redis的key的名字
          //  set  user.all   hello
        String usersJson=redisTemplate.boundValueOps("user.all").get(); //get  user.all
//             将json转成User的集合框架
        if(usersJson!=null){
            //缓存里面有数据
            List<User>  users=mapper.readValue(usersJson,new TypeReference<List<User>>(){});
            return  users;
        }else {
//         2.如果redis没有数据,从mysql数据库中读取,读取出来,存在redis缓存里面
            List<User> users=userMapper.selectAllUser();//从数据库里面读取
//            List<User> 转成json对象
            String json=mapper.writeValueAsString(users);
            redisTemplate.boundValueOps("user.all").set(json);// set  user.all   hello
            return  users;
        }
    }

    @Override
    public User Login(String username, String password) {
        //先根据用户名查询用户 在匹对密码(专门的比对方法)
    User user=userMapper.selectByUsername(username);
//    比对密码
   String table_password=user.getPassword();//数据库中查询的密码,加密后的密码
   if (encoder.matches(password,table_password)){
       //前端明文密码  后面是加密后的密文密码   true 比对成功
       return  user;
   }
//      比对不成null
    return  null;
    }

    @Override
    public User getUserByUsername(String username) {
        return userMapper.selectByUsername(username);
    }

    @Override
    public boolean register(User user) {
//        用户名已存在,注册不成功
        if (userMapper.selectByUsername(user.getUsername()) != null) {
            return false;
        }
        //注册成功
        //获取明文密码
        String password=user.getPassword();//control发送过来,用户前端发送给control
        //加密
        password=encoder.encode(password);//加密后的字符串
        user.setPassword(password);//将加密后的密码重新复制给user对象,那么mapper获得就是加密后的密码了
        return userMapper.insertIntoUser(user);
    }
}
